/** 用于取消操作的对象 */
class AbortToken {

  constructor() {
    this.task = undefined;
  }

  /**
   * 取消网络操作
   */
  abort() {
    this.task && this.task.abort && this.task.abort();
  }
}


/**
 * 返回用于取消网络请求的token
 */
export const getAbortToken = () => {
  return new AbortToken();
}

/// 增强promise
Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};

/**
 * 发送网络请求
 * @auth chenkefeng@kuaicto.com
 * 
 * @param url
 *        请求地址
 * @param method
 *        请求方式（GET, POST, DELETE, PUT）
 */
export const send = (url, method = 'GET', params = {}, abortToken, isLogin = false) => {
  
  let baseURL = '';
  if (!wx.requestBaseURL || typeof (wx.requestBaseURL) !== 'function') {
    console.error(`您需要在app.js中定义如下代码（仅demo展示）：

      wx.profileEnv = 'prod';   // prod  env
      wx.requestBaseURL = () => {
        if (wx.profileEnv !== 'prod') {
          return 'http://测试环境基地址';
        }
        return 'http://生成环境基地址';
      };
      wx.imageBaseURL = () => {
        return 'http://图片基地址';
      }
    `);
  } else {
    baseURL = wx.requestBaseURL();
  }
  
  if (!url.startsWith('http')) {
    if(url.startsWith('/') && baseURL.endsWith('/')){
      baseURL = baseURL.substring(0, baseURL.length - 1);
    }
    let donotDeedLine = url.startsWith('/') || baseURL.endsWith('/');
    
    url = `${baseURL}${donotDeedLine ? "" : "/"}${url}`;
  }
  let cookie = wx.getStorageSync('COOKIE_KEY') || ''; 
  let promiseResult = new Promise((resolve, reject) => {
    let requestTask = wx.request({
      url: url,
      method: method,
      data: params || {},
      header: {
        'Cookie': cookie
      },
      success: function (res) {
        let respData = res.data || {};
        if(res.statusCode !== 200){
          reject({
            code: respData.code || -1,
            message: respData.message || '服务器繁忙，请稍后重试' 
          });
          return;
        } 
        let respHeader = res.header || {};
        if(isLogin){
          wx.setStorageSync('COOKIE_KEY', respHeader['Set-Cookie'] || '');
        }
        resolve(respData);
      },
      fail: function (error) {
        let result = {
          code: -1,
          message: '服务器繁忙，请稍后重试'
        };

        if (error && error.errMsg && error.errMsg.indexOf('abort') >= 0){
          result.code = 0;
          result.message = '网络请求取消';
        }
        reject(result);
      }
    });
    if (abortToken) {
      abortToken.task = requestTask;
    }
  });
  return promiseResult;
}

export const doGet = (url, params, abortToken) => {
  return send(url, 'GET', params, abortToken);
}

export const doPost = (url, params, abortToken) => {
  return send(url, 'POST', params, abortToken);
}

export const doDelete = (url, params, abortToken) => {
  return send(url, 'DELETE', params, abortToken);
}

export const doPut = (url, params, abortToken) => {
  return send(url, 'PUT', params, abortToken);
}

export const doLogin = (url, params, abortToken) => {
  return send(url, 'POST', params, abortToken, true);
}